/*
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.spice.servlet.dispatcher;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public 
class SpiceDocumentFactory {

	private static final long serialVersionUID = 1L;

	private static 
	final String SCHEMA = "http://www.w3.org/2001/XMLSchema";

	private static 
	final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";

	protected static 
	final Logger SPICE_CONTEXT_REGISTRY = LoggerFactory.getLogger(SpiceDocumentFactory.class);

	protected 
	DocumentBuilderFactory getDocumentBuilderFactory() {
		return DocumentBuilderFactory.newInstance();
	}

	protected 
	void configureFactory(DocumentBuilderFactory factory) {
		factory.setNamespaceAware(true);
		factory.setValidating(true);
		try {
			factory.setAttribute(JAXP_SCHEMA_LANGUAGE, SCHEMA);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		}

	}

	public 
	XSDElements configureSpice(String absolutePath, String relativePath) {

		String initParameter = absolutePath + relativePath;
		final DocumentBuilderFactory factory = getDocumentBuilderFactory();
		configureFactory(factory);
		DocumentBuilder builder;
		Element element = null;
		try {
			builder = factory.newDocumentBuilder();
			builder.setEntityResolver(new SpiceEntityResolver(absolutePath));
			builder.setErrorHandler(new SpiceDocumentErrorHandler());
			
			SPICE_CONTEXT_REGISTRY.info("The init parameters are " + initParameter);
			final File file = new File(initParameter);

			final Document document = builder.parse(file);
			element = document.getDocumentElement();


		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return parseNodeContent(element);

	}

	protected XSDElements parseNodeContent(Element element) {
		NodeList list = element.getChildNodes();
		int size = list.getLength();
		final XSDElements xsdElements = new XSDElements();
		for (int i = 0; i < size; i++) {
			Node internalNode = list.item(i);
			
			SPICE_CONTEXT_REGISTRY.info("The internal nodes are " + internalNode);
			if (internalNode.getNodeName().endsWith(":scanpath")) {
				if (internalNode.hasAttributes()) {
					NamedNodeMap nodeMap = internalNode.getAttributes();
					Node packageNode = nodeMap.getNamedItem("package");
					SPICE_CONTEXT_REGISTRY.info("The Named Node Map is "
							+ packageNode.getTextContent());
					xsdElements.setScanpath(packageNode.getTextContent());
				}
			}else if (internalNode.getNodeName().endsWith(":views")) {
				if (internalNode.hasAttributes()) {
					NamedNodeMap nodeMap = internalNode.getAttributes();
					Node packageNode = nodeMap.getNamedItem("prefix");
					SPICE_CONTEXT_REGISTRY.info("The Named Node Map is "
							+ packageNode.getTextContent());
					xsdElements.setJspPrefix(packageNode.getTextContent());
					
					Node suffixNode = nodeMap.getNamedItem("suffix");
					SPICE_CONTEXT_REGISTRY.info("The Named Node Map is "
							+ suffixNode.getTextContent());
					xsdElements.setJspSuffix(suffixNode.getTextContent());
					
				}
			}
		}
		return xsdElements;
	}
}
